package org.maxgroundstation.groundstation.comm.service.gps;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

/**
 * Utility class for point of interest.
 * @author Scott Davis
 * 
 * Copyright (C) 2010  Scott Davis
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
public final class PointOfInterestUtil {

    // Static members.
    private static final String POI_DIR = System.getProperty("user.home") + File.separator + 
            "max_groundstation" + File.separator + "poi";
    private static final String SAVE_FILE = "poi_list.xml";
    
    /**
     * Private constructor for utility class.
     */
    private PointOfInterestUtil() {}
    
    /**
     * Save a list of points of interest to a XML file.
     * @param poiList a list of points of interest.
     */
    public static void savePointsOfInterest(List<PointOfInterest> poiList) {
        
        FileOutputStream stream = null;
        
        try {
            Document outputDoc = new Document();
            //DocType dtd = new DocType("poi_list", POI_DIR + File.separator + DTD_FILE);
            //outputDoc.setDocType(dtd);
            Element poiListElement = new Element("poi_list");
            outputDoc.addContent(poiListElement);
            outputDoc.setRootElement(poiListElement);
            
            Iterator<PointOfInterest> i = poiList.iterator();
            while (i.hasNext()) {
                PointOfInterest poi = i.next();
                
                Element poiElement = new Element("poi");
                poiListElement.addContent(poiElement);
                poiElement.setAttribute("name", poi.getName());
                poiElement.setAttribute("latitude", Double.toString(poi.getLatitude()));
                poiElement.setAttribute("longitude", Double.toString(poi.getLongitude()));
                
                DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ssz");
                dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
                poiElement.setAttribute("timestamp", dateFormatter.format(poi.getTimestamp()));
                
                Element descriptionElement = new Element("description");
                descriptionElement.addContent(poi.getDescription());
                poiElement.addContent(descriptionElement);
                
                Element videoSnapshotListElement = new Element("video_snapshot_list");
                poiElement.addContent(videoSnapshotListElement);
                
                Iterator<String> j = poi.getSnapshotFileNames().iterator();
                while (j.hasNext()) {
                    String snapshotFilename = j.next();
                    Element videoSnapshotElement = new Element("video_snapshot");
                    videoSnapshotElement.setAttribute("filename", snapshotFilename);
                    videoSnapshotListElement.addContent(videoSnapshotElement);
                }
            }
            
            File saveFile = new File(POI_DIR, SAVE_FILE);
            
            // Create poi directory if it doesn't already exist.
            if (!saveFile.getParentFile().exists()) {
                saveFile.getParentFile().mkdirs();
            }
            
            XMLOutputter fmt = new XMLOutputter();
            fmt.setFormat(Format.getPrettyFormat());
            stream = new FileOutputStream(saveFile);
            OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8");
            fmt.output(outputDoc, writer);
        } 
        catch (Exception e) {
            e.printStackTrace(System.err);
        } 
        finally {
            try {
                if (stream != null) stream.close();
            }
            catch (Exception e) {
                e.printStackTrace(System.err);
            }
        }
    }
    
    /**
     * Loads a list of points of interest from an XML file.
     * @return list of points of interest.
     */
    public static List<PointOfInterest> loadPointsOfInterest() {
        List<PointOfInterest> poiList = new ArrayList<PointOfInterest>();
        
        FileInputStream stream = null;
        
        try {
            File saveFile = new File(POI_DIR, SAVE_FILE);
            if (saveFile.exists()) {
                stream = new FileInputStream(saveFile);
                InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
                //SAXBuilder saxBuilder = new SAXBuilder(true);
                SAXBuilder saxBuilder = new SAXBuilder(false);
                Document inputDoc = saxBuilder.build(reader);
                
                Element poiListElement = inputDoc.getRootElement();
                
                Iterator i = poiListElement.getChildren().iterator();
                while (i.hasNext()) {
                    Element poiElement = (Element) i.next();
                    PointOfInterest poi = new PointOfInterest();
                    
                    poi.setName(poiElement.getAttributeValue("name"));
                    
                    poi.setLatitude(Double.parseDouble(poiElement.getAttributeValue("latitude")));
                    
                    poi.setLongitude(Double.parseDouble(poiElement.getAttributeValue("longitude")));
                    
                    DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ssz");
                    dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
                    poi.setTimestamp(dateFormatter.parse(poiElement.getAttributeValue("timestamp")));
                    
                    Element descriptionElement = poiElement.getChild("description");
                    poi.setDescription(descriptionElement.getTextTrim());
                    
                    Element videoSnapshotListElement = poiElement.getChild("video_snapshot_list");
                    if (videoSnapshotListElement != null) {
                        Iterator j = videoSnapshotListElement.getChildren().iterator();
                        while (j.hasNext()) {
                            Element videoSnapshotElement = (Element) j.next();
                            poi.addSnapshotFileName(videoSnapshotElement.getAttributeValue("filename"));
                        }
                    }
                    
                    poiList.add(poi);
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace(System.err);
        }
        finally {
            try {
                if (stream != null) stream.close();
            }
            catch (Exception e) {
                e.printStackTrace(System.err);
            }
        }
        
        return poiList;
    }
}